#include "PrecompiledHeader.h"
#include "Ini.h"

/*--------------------------------------------------------------------------*/

IniFile::IniFile(const std::string& path) :
	IResource(path)
{
	this->LoadFile();
}

/*--------------------------------------------------------------------------*/

IniFile::~IniFile()
{
	for (std::list<IniFileSection*>::iterator i = this->m_iniSectionsList.begin(); i != this->m_iniSectionsList.end(); ++i)
	{
		delete(*i);
	}
}

/*--------------------------------------------------------------------------*/

int IniFile::GetInteger(const std::string&  section, const std::string&  name, const int& defaultVal) const
{
	if (!this->m_iniSectionsList.size())
	{
		return defaultVal;
	}

	IniFileItem* item = this->GetItem(section, name);

	if (item)
	{
		return item->GetInt();
	}
	else
	{
		//LogE(1) << "Section " << section << " in file " << this->GetPath() << " not exists";
		return defaultVal;
	}
}

/*--------------------------------------------------------------------------*/

float IniFile::GetFloat(const std::string& section, const std::string& name, const float& defaultVal) const
{
	if (!this->m_iniSectionsList.size())
	{
		return defaultVal;
	}

	IniFileItem* item = this->GetItem(section, name);

	if (item)
	{
		return item->GetFloat();
	}
	else
	{
		//LogE(1) << "Section " << section << " in file " << this->GetPath() << " not exists";
		return defaultVal;
	}
}

/*--------------------------------------------------------------------------*/

std::string IniFile::GetString(const std::string& section, const std::string& name, const std::string& defaultVal) const
{
	if (!this->m_iniSectionsList.size())
	{
		return defaultVal;
	}

	IniFileItem* item = this->GetItem(section, name);

	if (item)
	{
		return item->GetString();
	}
	else
	{
		//LogE(1) << "Section " << section << " in file " << this->GetPath() << " not exists";
		return defaultVal;
	}
}

/*--------------------------------------------------------------------------*/

void IniFile::LoadFile()
{
	std::ifstream file(this->GetPath().c_str());

	if (!file.is_open())
	{
		//LogE(1) << "File " << this->GetPath() << " not found.";
		return;
	}

	const int lineLength = 512;
	char tmpt[lineLength];
	IniFileSection* active_section = NULL;

	while (file.getline(tmpt, lineLength))
	{
		if (tmpt[0] == '#')
		{
			continue;
		}

		if (tmpt[0] == '\n')
		{
			continue;
		}

		if (tmpt[0] == '[')
		{
			int i = 1;
			std::string section;

			while (tmpt[i] != ']')
			{
				section += tmpt[i];
				++i;
			}

			if (active_section != NULL)
			{
				this->m_iniSectionsList.push_back(active_section);
			}

			active_section = new IniFileSection(section);
		}
		else
		{
			int i = 0;
			bool isName = true;
			std::string name, value;

			while (tmpt[i] != '\0')
			{
				if (isName)
				{
					if (tmpt[i] != '=')
					{
						name += tmpt[i];
					}
					else
					{
						isName = false;
					}
				}
				else
				{
					value += tmpt[i];
				}

				++i;
			}

			if (active_section == NULL)
			{
				active_section = new IniFileSection("");
			}

			active_section->AddItem(name, value);
		}
	}

	file.close();

	if (active_section != NULL)
	{
		this->m_iniSectionsList.push_back(active_section);
	}
}

/*--------------------------------------------------------------------------*/

IniFileSection* IniFile::GetSection(const std::string& section) const
{
	for (std::list<IniFileSection*>::const_iterator I = this->m_iniSectionsList.begin(); I != this->m_iniSectionsList.end(); I++)
	{
		if ((*I)->GetName() == section)
		{
			return (*I);
		}
	}

	return NULL;
}

/*--------------------------------------------------------------------------*/

IniFileItem* IniFile::GetItem(const std::string& section, const std::string& name) const
{
	IniFileSection* sec = this->GetSection(section);

	if (sec == NULL)
	{
		//LogW(1) << "Section [" << section << "] in file " << this->GetPath() << " not found.";
		return NULL;
	}

	IniFileItem* item = sec->GetItem(name);

	if (item == NULL)
	{
		//LogW(1) << "Variable " << section << " in file " << this->GetPath() << " not found.";
		return NULL;
	}

	return item;
}

/*--------------------------------------------------------------------------*/

const std::string& IniFile::GetPath() const
{
	return this->m_path;
}

/*--------------------------------------------------------------------------*/

void IniFile::SetPath(const std::string& path)
{
	this->m_path = path;
}

/*--------------------------------------------------------------------------*/

